import {MATCH_CASE_STRING, MdcCase, processCaseString} from "./processCaseString";
import {MATCH_TABLE_STRING, MdcTable, processTableString} from "./processTableString";

export type Mdc = string | MdcCase | MdcTable

const processorList = [] as {
    regexp: RegExp,
    processor: (str: string, processCountIndex: number) => Mdc,
}[]

/**
 * 注册解析器
 * @author  韦胜健
 * @date    2020/9/18 19:45
 */
export function registryProcessor(regexp: RegExp, processor: (str: string) => Mdc) {
    processorList.push({regexp, processor})
}

/**
 * 解析整个md字符串
 * @author  韦胜健
 * @date    2020/9/16 9:53
 */
export function processMdc(mdc: string | undefined): Mdc[] {

    if (!mdc) {
        return []
    }

    const processorMatchString = processorList.reduce((ret, item, processorIndex) => {
        const {regexp} = item
        const stringList = [] as string[]
        mdc = mdc!.replace(regexp, (...args) => {
            stringList.push(args[1].trim())
            return `:::separator::: process_${processorIndex} :::separator:::`
        })
        ret.push(stringList)
        return ret
    }, [] as string[][])


    const processorCountIndex = [] as number[]
    const ret = mdc.split(':::separator:::')
        .map(str => str.trim())
        .reduce((ret, item) => {

            const match = item.match(/process_(.*)/)
            if (!!match) {
                const processorIndex = Number(match[1])
                if (processorCountIndex[processorIndex] == null) {
                    processorCountIndex[processorIndex] = 0
                }
                const pci = (processorCountIndex[processorIndex])++
                ret.push(processorList[processorIndex].processor(processorMatchString[processorIndex][pci], pci))
            } else {
                !!item && ret.push(item)
            }

            return ret
        }, [] as Mdc[])
    return ret
}

registryProcessor(MATCH_TABLE_STRING, processTableString)
registryProcessor(MATCH_CASE_STRING, processCaseString)
